#!/usr/bin/env python3
#
# Copyright 2018 Google LLC
#
# Use of this source code is governed by an MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT.

import argparse
import os
import pathlib
import subprocess
import sys

wd = pathlib.Path(__file__).parent
sys.path.append(str(wd / "python"))

import fetchhash
import formatperf
import formattv

def writechanged(path, content):
    if (not path.exists()) or path.read_text() != content:
        path.write_text(content)

def hash_input_files(inp, outp):
    done = set()
    with outp.open("w") as outf:
        with inp.open() as inf:
            for l in inf:
                t, n = l.split(maxsplit=1)
                if t != "INPUT":
                    continue
                n = n[:-1]
                if n in done:
                    continue
                done.add(n)
                npath = pathlib.Path(n)
                sh = fetchhash.hash_file(npath)
                outf.write(f"{sh} {n}\n")

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('input', type=pathlib.Path, nargs='?')
    parser.add_argument('--iacr', action='store_true')
    return parser.parse_args()

def main():
    args = parse_args()
    work = wd / "work"
    work.mkdir(parents = True, exist_ok = True)
    fetch = work / "fetch"
    fetch.mkdir(parents = True, exist_ok = True)
    texinputs = [wd]

    if args.iacr:
        iacrtrans = work / "iacrtrans"
        if not iacrtrans.is_dir():
            fetchhash.fetch_file(fetch / "iacr_tosc.zip",
                "https://tosc.iacr.org/public/journals/6/iacr_tosc.zip",
                "dac48968ba4259261b06028eda1a880c3a8f411f7cac62060b308a7acb68a71f")
            uz = fetch / "iacrtrans"
            if uz.exists():
                subprocess.run(["rm", "-rf", str(uz)], check=True)
            subprocess.run(["unzip", "iacr_tosc.zip"], cwd=fetch, check=True)
            uz.rename(iacrtrans)
        texinputs.append(iacrtrans)

    latexrun = work / "latexrun"
    if not latexrun.is_file():
        fl = fetch / "latexrun"
        fetchhash.fetch_file(fl,
            "https://raw.githubusercontent.com/aclements/latexrun/38ff6ec2815654513c91f64bdf2a5760c85da26e/latexrun",
            "2f144fc6257da7d47475165d2599ecb779d48ca25eb88c5bca4fbc9468a34782")
        fl.chmod(0o755)
        fl.rename(latexrun)

    tvs = work / "test_vectors.tex"
    if not tvs.is_file():
        ttvs = tvs.with_name("tmp_" + tvs.name)
        jf = wd.resolve().parent / "test_vectors" / "ours" / "HPolyC"
        jf /= "HPolyC_XChaCha12_32_AES256.json"
        formattv.write_tvs(jf, ttvs)
        ttvs.rename(tvs)

    performancetex =  work / "performance.tex"
    if not performancetex.is_file():
        formatperf.formatperf(performancetex, wd / "performance")

    rp = subprocess.run(["git", "rev-parse", "HEAD"], cwd=wd, check=True,
        stdout=subprocess.PIPE, errors='strict')
    gitstate = rp.stdout.strip()
    di = subprocess.run(["git", "diff-index", "--quiet", "HEAD", "--"], cwd=wd)
    if di.returncode != 0:
        gitstate += "+"
    gitstate += "\n"
    writechanged(work / "git.tex", gitstate)

    inputfile = wd / "eprint.tex"
    latex = "lualatex"
    if args.iacr:
        inputfile = wd / "iacr.tex"
        latex = "xelatex"

    if args.input is not None:
        inputfile = args.input

    texinputs.append("")
    env = dict(os.environ)
    env["TEXINPUTS"] = ":".join(str(d) for d in texinputs)
    outdir = work / "latex.out"
    subprocess.run([str(latexrun),
            "-O", str(outdir),
            "--latex-cmd", latex,
            "--bibtex-cmd", "biber",
            str(inputfile)],
        cwd=wd, check=True, env=env)
    hash_input_files(
        outdir / (inputfile.stem + ".fls"),
        outdir / (inputfile.stem + ".sha256"))

if __name__ == "__main__":
    main()
